﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using OthelloGame;
using System.Diagnostics;

namespace OthelloCognition
{
    public class MinmaxSolverVG : AbstractSolver
    {
        private AbstractHeuristic h;
        private OthelloBoardLocation best_loc;
        //private Hashtable move_utility = new Hashtable();

        public MinmaxSolverVG(Heuristics heur)
        {
            h = HeuristicFactory.getHeuricstic(heur);
        }

        public override SolverEnum SolverName()
        {
            return SolverEnum.MinimaxVG;
        }

        protected override void examineBoard(OthelloGameBoard board)
        {
            Console.WriteLine(board.AvailableOptionLocations.Count.ToString());
            for (int i = 0; i < 2; ++i)
            {
                OthelloGameBoard best_board = MaxMove(board, 0, i);
                move = best_loc;
            }
        }

        private OthelloGameBoard MaxMove(OthelloGameBoard board, int current_depth, int maxply)
        {
            //Console.WriteLine("MaxMove: " + current_depth.ToString());
            if (current_depth == maxply) return board;

            int best_max_score = -100000;

            OthelloGameBoard best_max = null;

            foreach (OthelloBoardLocation possible_move in board.AvailableOptionLocations)
            {
                OthelloGameBoard child = expandState(board, possible_move);

                OthelloGameBoard max = MinMove(child, current_depth, maxply);

                if (max.AvailableOptionLocations.Count > best_max_score)
                {
                    if (current_depth == maxply - 1)
                    {
                        best_loc = possible_move;
                    }
                    best_max = max;
                    best_max_score = max.AvailableOptionLocations.Count;
                }
            }

            Debug.Assert((best_max != null), "Assertion Failure MaxMove");

            return best_max;
        }

        private OthelloGameBoard MinMove(OthelloGameBoard board, int current_depth, int maxply)
        {
            //Console.WriteLine("MinMove: " + current_depth.ToString());
            int best_min_score = 100000;

            OthelloGameBoard best_min = null;

            foreach (OthelloBoardLocation possible_move in board.AvailableOptionLocations)
            {
                OthelloGameBoard child = expandState(board, possible_move);

                OthelloGameBoard min = MaxMove(child, current_depth + 1, maxply);

                if (min.AvailableOptionLocations.Count < best_min_score)
                {
                    best_min = min;
                    best_min_score = min.AvailableOptionLocations.Count;
                }
            }

            if (best_min == null) return board;

            //Debug.Assert((best_min != null), "Assertion Failure in MinMove");

            return best_min;
        }

        private int heuristic(OthelloGameBoard board, OthelloBoardLocation pit)
        {
            OthelloGameBoard nb = expandState(board, pit);
            return h.evaluate(nb, nb.PlayersTurn);
        }
    }
}